<?php

require_once(WSB_MODULES_PATH .'sherpa/models/BaseGateway.php');
require_once(WSB_MODULES_PATH .'sherpa/models/BasketProducts.php');
require_once(WSB_MODULES_PATH .'sherpa/models/Basket.php');

class Sherpa_Model_BasketGateway extends Sherpa_Model_BaseGateway
{

	/**
	 * @return Sherpa_Model_Basket
	 */
	public function fetchBasket()
	{
		$basketId = $this->_getBasketId();
		$select = $this->getDbSelect();
		$select->from(array('b' => 'sherpa_baskets'));
		$select->joinLeft(array('o' => 'sherpa_orders'), 'o.basketId = b.id AND basketId IS NULL', array());
		$select->where('b.sessionId = ?', Zend_Session::getId());
		$select->where('b.id = ?', $basketId);
		return new Sherpa_Model_Basket($select->query()->fetch());
	}

	/**
	 * @return integer
	 */
	public function countProducts()
	{
		$basketId = $this->_getBasketId();
		if(empty($basketId)) {
			return 0;
		} else {
			$select = $this->getDbSelect();
			$select->from(array('b' => 'sherpa_productToBasket'), array('SUM(quantity)'));
			// Child product
			$select->join(array('cp' => 'sherpa_products'), 'cp.id = b.productId', array());
			// Parent product
			$select->join(array('pp' => 'sherpa_products'), 'pp.id = cp.parentId', array());
			$select->where('pp.active = 1');
			$select->where('pp.available = 1');
			$select->where('pp.archived IS NULL');
			$select->where('cp.active = 1');
			$select->where('cp.available = 1');
			$select->where('cp.archived IS NULL');
			$select->where('b.basketId = ?', $basketId);
			return intval($select->query()->fetchColumn(0));
		}
	}

	/**
	 * @param integer $languageId
	 * @return Sherpa_Model_BasketProducts
	 */
	public function fetchProducts($languageId)
	{
		$basketId = $this->_getBasketId();
		if(empty($basketId)) {
			return new Sherpa_Model_BasketProducts(array());
		}

		$select = $this->getDbSelect();
		$select->distinct();
		// Parent product
		$select->from(array('pp' => 'sherpa_products'), array('parentProductId' => 'id', 'parentArticleNumber' => 'articleNumber', 'parentProductName' => 'productName', 'parentProductLine' => 'productLine'));
		// Child product
		$select->join(array('cp' => 'sherpa_products'), 'pp.id = cp.parentId', array('articleNumber', 'productName', 'productLine', 'colorApplicationId'));
		$select->join(array('cptb' => 'sherpa_productToBasket'), 'cptb.productId = cp.id');
		$select->join(array('s' => 'sherpa_sizes'), 's.id = cp.sizeId', array('size' => 's.size'));
		$select->where('cptb.basketId = ?', $basketId);
		$select->where('pp.languageId = ?', $languageId);
		$select->where('pp.active = 1');
		$select->where('pp.available = 1');
		$select->where('pp.archived IS NULL');
		$select->where('cp.active = 1');
		$select->where('cp.available = 1');
		$select->where('cp.archived IS NULL');
		$select->order('cptb.modified DESC');
		//$this->_setActiveWhereClause($select, 'pp.activeFrom', 'pp.activeTo');
		//$this->_setAvailableWhereClause($select, 'pp.availableFrom', 'pp.availableTo');
		$rows = $select->query()->fetchAll();

		// Vererbung von Inhalten von Parent- zu Child-Produkten
		foreach($rows AS $i=>$row) {
			if(empty($row['articleNumber'])) {
				$rows[$i]['articleNumber'] = $row['parentArticleNumber'];
			}
			if(empty($row['productName'])) {
				$rows[$i]['productName'] = $row['parentProductName'];
			}
			if(empty($row['productLine'])) {
				$rows[$i]['productLine'] = $row['parentProductLine'];
			}
			unset($rows[$i]['parentArticleNumber']);
			unset($rows[$i]['parentProductName']);
			unset($rows[$i]['parentProductLine']);
		}

		return new Sherpa_Model_BasketProducts($rows);
	}

	/**
	 * @param integer $childProductId
	 * @return integer Anzahl betroffener Zeilen der Tabelle
	 */
	public function removeProduct($childProductId)
	{
		$basketId = $this->_getBasketId();
		if(empty($basketId)) {
			return 0;
		}
		$db = $this->getDb();
		return $db->delete('sherpa_productToBasket', 'productId=' . $childProductId . ' AND basketId=' . $basketId);
	}

	/**
	 * @return integer Anzahl betroffener Zeilen der Tabelle
	 */
	public function removeAllProducts()
	{
		$basketId = $this->_getBasketId();
		if(empty($basketId)) {
			return 0;
		}
		$db = $this->getDb();
		return $db->delete('sherpa_productToBasket', 'basketId=' . $basketId);
	}

	/**
	 * @param integer $childProductId
	 * @param integer $quantity
	 * @return integer Anzahl betroffener Zeilen der Tabelle
	 */
	public function updateProductQuantity($childProductId, $quantity)
	{
		$basketId = $this->_getBasketId();
		if(empty($basketId)) {
			return 0;
		}
		if(empty($quantity)) {
			return $this->removeProduct($childProductId);
		} else {
			$db = $this->getDb();
			$data = array(
				'quantity' => $quantity
			);
			return $db->update('sherpa_productToBasket', $data, 'productId=' . $childProductId . ' AND basketId=' . $basketId);
		}
	}

	/**
	 * @param integer $childProductId
	 * @param integer $quantity
	 * @param string $currencyCode
	 * @return integer Anzahl betroffener Zeilen der Tabelle
	 */
	public function addProduct($childProductId, $quantity, $currencyCode)
	{
		$basketId = $this->_getBasketId();
		if(empty($basketId)) {
			$basketId = $this->_createBasket();
		}
		if(empty($basketId)) {
			throw new Exception('Could not create new basket');
		}
		return $this->_addProduct($basketId, $childProductId, $quantity, $currencyCode);
	}

	/**
	 * @param integer $childProductId
	 * @param string $currencyCode
	 * @return Sherpa_Model_Price
	 */
	private function _fetchPrice($childProductId, $currencyCode)
	{
		require_once(WSB_MODULES_PATH .'sherpa/models/PriceGateway.php');
		$gateway = new Sherpa_Model_PriceGateway();
		return $gateway->fetchChildProductPrice($childProductId, $currencyCode);
	}

	/**
	 * @param integer $basketId
	 * @param integer $childProductId
	 * @param integer $quantity
	 * @param string $currencyCode
	 * @return integer Anzahl betroffener Zeilen der Tabelle
	 */
	private function _addProduct($basketId, $childProductId, $quantity, $currencyCode)
	{
		$price = $this->_fetchPrice($childProductId, $currencyCode);
		if(!$price->isLoaded()) {
			return 0;
		}

		if(!$this->_isValidProduct($childProductId)) {
			return 0;
		}

		$select = $this->getDbSelect();
		$select->from(array('ptb' => 'sherpa_productToBasket'));
		$select->where('ptb.productId = ?', $childProductId);
		$select->where('ptb.basketId = ?', $basketId);
		$row = $select->query()->fetch();

		// Insert
		if(empty($row)) {
			$data = array(
				'productId' => $childProductId,
				'basketId' => $basketId,
				'quantity' => $quantity,
				'price' => $price->getPrice(),
				'currencyCode' => $currencyCode,
				'modified' => new Zend_Db_Expr('NOW()'),
				'created' => new Zend_Db_Expr('NOW()')
			);
			return $this->getDb()->insert('sherpa_productToBasket', $data);

		// Update
		} else {
			$data = array(
				'quantity' => $row['quantity'] + $quantity,
				'price' => $price->getPrice(),
				'currencyCode' => $currencyCode,
				'modified' => new Zend_Db_Expr('NOW()')
			);
			return $this->getDb()->update('sherpa_productToBasket', $data, 'productId=' . $childProductId . ' AND basketId=' . $basketId);
		}
	}

	/**
	 * @param integer $childProductId
	 * @return boolean
	 */
	private function _isValidProduct($childProductId)
	{
		$select = $this->getDbSelect();
		// pp -> Parent product, cp -> Child product
		$select->from(array('pp' => 'sherpa_products'));
		$select->join(array('cp' => 'sherpa_products'), 'pp.id = cp.parentId', array());
		$select->where('pp.active = 1');
		$select->where('pp.available = 1');
		$select->where('pp.archived IS NULL');
		$select->where('cp.active = 1');
		$select->where('cp.available = 1');
		$select->where('cp.archived IS NULL');
		//$this->_setActiveWhereClause($select, 'pp.activeFrom', 'pp.activeTo');
		//$this->_setAvailableWhereClause($select, 'pp.availableFrom', 'pp.availableTo');
		$select->where('cp.id = ?', $childProductId);
		$row = $select->query()->fetch();
		return !empty($row);
	}

	/**
	 * @param string
	 * @return integer
	 */
	private function _getBasketId($sessionId = null)
	{
		if(is_null($sessionId)) {
			$sessionId = Zend_Session::getId();
		}
		$select = $this->getDbSelect();
		$select->from(array('b' => 'sherpa_baskets'));
		//$select->joinLeft(array('o' => 'sherpa_orders'), 'o.basketId = b.id AND basketId IS NULL', array());
		$select->joinLeft(array('o' => 'sherpa_orders'), 'o.basketId = b.id', array());
		$select->where('b.sessionId = ?', $sessionId);
		$select->where('o.id IS NULL');
		$row = $select->query()->fetch();
		if(is_array($row) && (count($row) > 0)) {
			return intval($row['id']);
		}
		return 0;
	}

	/**
	 * @param string $sessionId
	 * @return integer
	 */
	private function _createBasket($sessionId = null)
	{
		if(is_null($sessionId)) {
			$sessionId = Zend_Session::getId();
		}
		$basketId = $this->_getBasketId($sessionId);
		if($basketId > 0) {
			return $basketId;
		} else {
			$db = $this->getDb();
			$data = array(
				'feuserId' => NULL,
				'sessionId' => $sessionId,
				'created' => new Zend_Db_Expr('NOW()')
			);
			$db->insert('sherpa_baskets', $data);
			return $db->lastInsertId('sherpa_baskets');
		}
	}

}
